package com.chenliang.sd.dao;


import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import com.chenliang.sd.po.Student;
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @program: springdata
 * @description:
 * @author: 陈亮
 * @create: 2022-03-05 00:05
 */

//public interface StudentRepository extends CrudRepository<Student,Long> {
public interface StudentRepository extends PagingAndSortingRepository<Student, Long>
        , QuerydslPredicateExecutor<Student> {

    /**
     * dao继承了CrudRepository 或者 PagingAndSortingRepository 可以实现一些通用的crud功能
     * 但是我们可以进行过一些自定义操作
     * 1: jpql (方法名随意取,不能实现动态sql)
     * 2: 规定方法名(查询或者删除操作,不能实现动态sql)
     * 3: Query By Example
     * 4: 通过Specifications
     * 5: Querydsl
     */


    //  自定义jpql CRUD  start

    /**
     * 自定义jpql操作1:
     * 结合@Query注解进行查询
     * 查询全部可以省略select
     * 通过数字进行参数传递
     *
     * @param name
     * @return
     */
    @Query(" from Student where name=?1")
    List<Student> findStudentByStuName(String name);

    /**
     * 自定义jpql操作2:
     * 结合@Query注解进行查询
     * 查询全部可以省略select
     * 通过参数名进行传递,但是需要添加注解@Param
     *
     * @param name
     * @return
     */
    @Query(" from Student where name=:name")
    List<Student> findStudentByStuName2(@Param("name") String name);


    /**
     * nativeQuery=true 标识构建原生sql查询
     *
     * @param name
     * @return
     */
    @Query(value = "select * from student where stu_name=:name", nativeQuery = true)
    List<Student> findStudentByStuName3(@Param("name") String name);

    /**
     * 更新操作
     * 增删改必须开启事务,和添加@Modify的注解
     * 只不过事务注解我们通常添加在逻辑层
     *
     * @param name
     * @param id
     * @return
     */
    @Transactional   // 事务控制
    @Modifying  // 告诉speigndatajpa 这是增删改的操作
    @Query("UPDATE Student s set s.name=:name where s.id=:id")
    Integer updateStudentById(@Param("name") String name, @Param("id") Long id);


    @Transactional   // 事务控制
    @Modifying  // 告诉speigndatajpa 这是增删改的操作
    @Query("DELETE from Student s  where s.id=?1")
    Integer deleteStudentById(Long id);


    /**
     * jpql是不支持插入操作,但是这里是通过hibernate实现的,所以支持伪插入
     * 插入查询出来数据,有寄吧用?
     *
     * @param id
     * @return
     */
    @Transactional   // 事务控制
    @Modifying  // 告诉speigndatajpa 这是增删改的操作
    @Query("INSERT INTO  Student (name) SELECT s.name from Student s where s.id=?1")
    Integer insertStudent(Long id);

    //  自定义jpql CRUD  end

    /**
     * 简单的sql定制抽象防范,不需要实现
     *
     * @param name
     * @return
     */
    List<Student> findByName(String name);
}
